package com.party.common.utils;

import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Enumeration;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author wenqiang.luo date:16/4/12
 */
public final class HttpServletRequestUtils {

    static Logger logger = LoggerFactory.getLogger(HttpServletRequestUtils.class);

    static final Pattern ieP = Pattern.compile("msie ([\\d.]+)");
    static final Pattern firefoxP = Pattern.compile("firefox\\/([\\d.]+)");
    static final Pattern chromeP = Pattern.compile("chrome\\/([\\d.]+)");
    static final Pattern operaP = Pattern.compile("opera.([\\d.]+)");
    static final Pattern edgeP = Pattern.compile("edge\\/([\\d.]+)");
    static final Pattern safariP = Pattern.compile("version\\/([\\d.]+).*safari");
    static List<Pattern> patterns = Lists.newArrayList();

    static {
        if (patterns.size() == 0) {
            patterns.add(ieP);
            patterns.add(firefoxP);
            patterns.add(chromeP);
            patterns.add(operaP);
            patterns.add(safariP);
            patterns.add(edgeP);
        }
    }

    /**
     * 私有构造方法
     */
    private HttpServletRequestUtils() {}

    public static Map<String,Object> getHeaders(HttpServletRequest request) {
        Map<String, Object> headers = Maps.newHashMap();
        Enumeration headerNames = request.getHeaderNames();
        while (headerNames.hasMoreElements()) {
            String key = (String) headerNames.nextElement();
            String value = request.getHeader(key);

            headers.put(key, value);
        }
        return headers;
    }

    /**
     * @param request request
     * @return
     * @Author yifeng
     * @Description 获取ip
     * @Date 13:50 2019/4/26
     **/
    public static String getRemoteIpAddress(HttpServletRequest request) {
        String ip = request.getHeader("x-forwarded-for");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("http_client_ip");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_X_FORWARDED_FOR");
        }
        // 如果是多级代理，那么取第一个ip为客户ip
        if (ip != null && ip.contains(",")) {
            ip = ip.substring(ip.lastIndexOf(",") + 1, ip.length()).trim();
        }
        return ip;
    }

    public static String getRequestUrl(HttpServletRequest request) {
        StringBuilder url = new StringBuilder();
        String scheme = request.getScheme();
        int port = request.getServerPort();
        String urlPath = request.getRequestURI();

        url.append (scheme);		// http, https
        url.append ("://");
        url.append (request.getServerName());
        if ((scheme.equals ("http") && port != 80)
                || (scheme.equals ("https") && port != 443)) {
            url.append (':').append(request.getServerPort());
        }
        url.append(urlPath);

        return url.toString();
    }

    public static boolean isAjaxRequest(HttpServletRequest request) {
        return  "XMLHttpRequest".equals(request.getHeader("X-Requested-With"));
    }

    /**
     * code 状态码，正常为0，异常的时候为非0。
     * data 查询到的结果。
     * country 国家。 country_id 国家代码。
     * area 地区名称（华南、华北...）。area_id 地区编号。
     * region 省名称。 region_id 省编号。
     * city 市名称。 city_id 市编号。
     * county 县名称。 county_id 县编号。
     * isp ISP服务商名称（电信/联通/铁通/移动...）。
     * isp_id ISP服务商编号。
     * ip 查询的IP地址。
     *
     * @param ip
     * @return
     */
    public static String getAddresses(String ip) {
        try {
            String urlStr = "http://ip.taobao.com/service/getIpInfo.php";
            String returnStr = getResult(urlStr, "ip=" + ip, "utf-8");
            JSONObject jsonObject = JSONObject.parseObject(returnStr);
            Integer code = (Integer) jsonObject.get("code");
            if (new Integer(0).equals(code)) {
                String region = "";
                String city = "";
                String isp = "";
                Map<String, Object> dataMap = null != jsonObject.get("data") ?
                        JSONObject.parseObject(jsonObject.get("data").toString(), Map.class) : null;
                if (null != dataMap) {
                    for (Map.Entry<String, Object> entry : dataMap.entrySet()) {
                        switch (entry.getKey()) {
                            case "region":
                                region = entry.getValue().toString();
                                break;
                            case "city":
                                city = entry.getValue().toString();
                                break;
                            case "isp":
                                isp = entry.getValue().toString();
                                break;
                            default:
                                break;
                        }
                    }
                    return region + "省" + city + "市 " + isp;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("根据IP解析运营商异常");
        }
        return null;
    }

    /**
     * @param urlStr   请求的地址
     * @param content  请求的参数 格式为：name=xxx&pwd=xxx
     * @param encoding 服务器端请求编码。如GBK,UTF-8等
     * @return
     */
    private static String getResult(String urlStr, String content, String encoding) {
        URL url = null;
        HttpURLConnection connection = null;
        try {
            url = new URL(urlStr);
            connection = (HttpURLConnection) url.openConnection();// 新建连接实例
            connection.setConnectTimeout(3000);// 设置连接超时时间，单位毫秒
            connection.setReadTimeout(3000);// 设置读取数据超时时间，单位毫秒
            connection.setDoOutput(true);// 是否打开输出流 true|false
            connection.setDoInput(true);// 是否打开输入流true|false
            connection.setRequestMethod("POST");// 提交方法POST|GET
            connection.setUseCaches(false);// 是否缓存true|false
            connection.connect();// 打开连接端口
            DataOutputStream out = new DataOutputStream(connection
                    .getOutputStream());// 打开输出流往对端服务器写数据
            out.writeBytes(content);// 写数据,也就是提交你的表单 name=xxx&pwd=xxx
            out.flush();// 刷新
            out.close();// 关闭输出流
            BufferedReader reader = new BufferedReader(new InputStreamReader(
                    connection.getInputStream(), encoding));// 往对端写完数据对端服务器返回数据
            // ,以BufferedReader流来读取
            StringBuffer buffer = new StringBuffer();
            String line = "";
            while ((line = reader.readLine()) != null) {
                buffer.append(line);
            }
            reader.close();
            return buffer.toString();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (connection != null) {
                connection.disconnect();// 关闭连接
            }
        }
        return null;
    }

    /**
     * @param userAgentStr 浏览器信息
     * @return
     * @Author yifeng
     * @Description 获取浏览器
     * @Date 11:59 2019/4/23
     **/
    public static String getBrowser(String userAgentStr) {
        String browser = "other";
        userAgentStr = userAgentStr.toLowerCase();
        System.out.println(userAgentStr);

        for (Pattern pattern : patterns) {
            Matcher matcher = pattern.matcher(userAgentStr);
            if (matcher.find()) {
                browser = matcher.group();
                System.out.println(browser);
            }
        }
        if (StringUtils.isNotEmpty(browser)) {
            browser = browser.replaceAll("\\/", " ");
        }
        System.out.println(browser);
        return browser;
    }

    /**
     * @param sUserAgent 浏览器信息
     * @return
     * @Author yifeng
     * @Description 获取操作系统
     * @Date 12:03 2019/4/23
     **/
    public static String getOs(String sUserAgent) {
        boolean isWin2K = sUserAgent.indexOf("Windows NT 5.0") > -1 || sUserAgent.indexOf("Windows 2000") > -1;
        if (isWin2K) {
            return "Win2000";
        }
        boolean isWinXP = sUserAgent.indexOf("Windows NT 5.1") > -1 || sUserAgent.indexOf("Windows XP") > -1;
        if (isWinXP) {
            return "WinXP";
        }
        boolean isWin2003 = sUserAgent.indexOf("Windows NT 5.2") > -1 || sUserAgent.indexOf("Windows 2003") > -1;
        if (isWin2003) {
            return "Win2003";
        }
        boolean isWinVista = sUserAgent.indexOf("Windows NT 6.0") > -1 || sUserAgent.indexOf("Windows Vista") > -1;
        if (isWinVista) {
            return "WinVista";
        }
        boolean isWin7 = sUserAgent.indexOf("Windows NT 6.1") > -1 || sUserAgent.indexOf("Windows 7") > -1;
        if (isWin7) {
            return "Win7";
        }
        boolean isWin10 = sUserAgent.indexOf("Windows NT 10") > -1 || sUserAgent.indexOf("Windows 10") > -1;
        if (isWin10) {
            return "Win10";
        }
        return "other";
    }
}
